# -*- coding: utf-8 -* 
import sys
import time
import sqlite3
import os
from threading import *
import subprocess
import yaml
import json
import pic_rc
import numpy as np
import matplotlib.pyplot as plt  # plt 用于显示图片
import matplotlib.image as mpimg  # mpimg 用于读取图片
import cv2
# os.environ["CUDA_VISIBLE_DEVICES"] = "-1"
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

# ros
import rospy
from sensor_msgs.msg import Image
from std_msgs.msg import Bool
import sys
sys.path.remove('/opt/ros/melodic/lib/python2.7/dist-packages')
import cv2
from cv_bridge import CvBridge, CvBridgeError

# 界面
from acupoint_choose import *
from mode_choose import *
from open import *
from open1 import *
from information import *
from bingli import *
from check import *
from acupoint_show import *
from pain import *

# import rospy
# 全局变量
thstop = False
thstop1 = False
user_name = 'default'
data_path = '/home/massage/GUI_v2/user_data/'
yaml_path = '/home/massage/massage_code/robot_ws/src/massage_control/nuc_communicate/scripts/config/'
def execute_cmd(cmd):
    shell_status, ret = subprocess.getstatusoutput(cmd)
    print(ret)
    check_rets=ret.split('\n')
    print(check_rets)
    check_status=[]
    for check_ret in check_rets:
        status=int(check_ret.split(':')[0])
        check_status.append(status)
    print(check_status)
    #check_status 分别代表相机，AGV,JAKA,按摩头以及PC上Node检查结果，0代表正常
    return check_status

# /********----------------------------界面槽函数---------------------------------------------------********/
# 开始界面
class MyWindow_start(QMainWindow, Ui_open):
    def __init__(self, parent=None):
        super(MyWindow_start, self).__init__(parent)
        self.setupUi(self)  # 这三行必须要有，ui——open载入open界面，（Qt生成open.ui文件，通过工具转成open.py文件）

    def begin_process(self):
        " "
        # acupoint transform node
        process_transform = subprocess.Popen("./startup_sh/acupoint_transform.sh", shell=True)

        # camera node
        process_camera = subprocess.Popen("./startup_sh/k4a.sh", shell=True)

        # # acupoint detect
        process_detect = subprocess.Popen("./startup_sh/acupoint_detect.sh", shell=True)
        #
        # # nuc pre
        process_nuc_pre = subprocess.Popen("./startup_sh/nuc_control.sh", shell=True)
        #
        # # nuc start
        process_nuc_start = subprocess.Popen("./startup_sh/nuc_start.sh", shell=True)

        # agv start
        process_agv = subprocess.Popen("./startup_sh/agv_start.sh", shell=True)

    def begin_process_with_new_terminate(self):
        # acupoint transform node
        process_transform = subprocess.Popen("gnome-terminal -t '1' -- ./startup_sh/acupoint_transform.sh", shell=True)

        # camera node
        process_camera = subprocess.Popen("gnome-terminal -t '2' -- ./startup_sh/k4a.sh", shell=True)

        # acupoint detect
        process_detect = subprocess.Popen("gnome-terminal -t '3' -- ./startup_sh/acupoint_detect.sh", shell=True)
        
        # # nuc kill -a
        process_nuc_kill = subprocess.Popen("gnome-terminal -t '4' -- ./startup_sh/nuc_kill.sh", shell=True)

        # # nuc pre
        process_nuc_pre = subprocess.Popen("gnome-terminal -t '5' -- ./startup_sh/nuc_control.sh", shell=True)
        #
        # # nuc start
        process_nuc_start = subprocess.Popen("gnome-terminal -t '6' -- ./startup_sh/nuc_start.sh", shell=True)

        # agv start
        process_agv = subprocess.Popen("gnome-terminal -t '7' -- ./startup_sh/agv_start.sh", shell=True)

    def closeEvent(self, event):
        """
        对MainWindow的函数closeEvent进行重构
        退出软件时结束所有进程
        :param event:
        :return:
        """
        reply = QtWidgets.QMessageBox.question(self,
                                               '本程序',
                                               "是否要退出程序？",
                                               QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
                                               QtWidgets.QMessageBox.No)
        # process_kill = subprocess.Popen("./startup_sh/host_kill.sh", shell=True)
        if reply == QtWidgets.QMessageBox.Yes:
            event.accept()
            os._exit(0)
            process_kill = subprocess.Popen("./startup_sh/host_kill.sh", shell=True)
        else:
            event.ignore()

# 选择新老用户界面
class MyWindow_user(QMainWindow, Ui_open1):
    def __init__(self, parent=None):
        super(MyWindow_user, self).__init__(parent)
        self.setupUi(self)
        global data_path
        self.user_name = 'default'
        self.yamlPath = data_path
        self.data = None
        self.mode = 0

    def get_name(self):
        self.user_name = self.textEdit.toPlainText()
        # print('user name', self.user_name)
        global user_name
        user_name = self.user_name

    def get_old_data(self):
        global user_name
        try:
            print(self.yamlPath + self.user_name + '.yaml')
            f = open(self.yamlPath + self.user_name + '.yaml', 'r', encoding='utf-8')
            self.data = yaml.load(f, Loader=yaml.FullLoader)
            with open(self.yamlPath +'Acu.yaml', "w") as f1:
                yaml.dump(self.data, f1, encoding="utf-8", allow_unicode=True)
            print('old user name find', self.user_name)

        except Exception as e:
            user_name = 'default'
            print('your input is wrong')
            QMessageBox.about(self, 'warning', 'this user is not exist，please try again')
        self.start_communicate()

    def start_communicate(self):
        " "
        # process_com = subprocess.Popen("./startup_sh/nuc_communicate.sh", shell=True)

    def closeEvent(self, event):
        """
        对MainWindow的函数closeEvent进行重构
        退出软件时结束所有进程
        :param event:
        :return:
        """
        reply = QtWidgets.QMessageBox.question(self,
                                               '本程序',
                                               "是否要退出程序？",
                                               QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
                                               QtWidgets.QMessageBox.No) 
                                    
        if reply == QtWidgets.QMessageBox.Yes:
            event.accept()
            os._exit(0)
            process_kill = subprocess.Popen("./startup_sh/host_kill.sh", shell=True)
        else:
            event.ignore()


# system check
class MyWindow_check(QMainWindow, Ui_system_check):
    def __init__(self, parent=None):
        super(MyWindow_check, self).__init__(parent)
        self.setupUi(self)  # 这三行必须要有，ui——open载入open界面，（Qt生成open.ui文件，通过工具转成open.py文件）

        self.flag = 1

    def check(self):
        # while not rospy.is_shutdown():
        check_result = execute_cmd('/home/massage/massage_code/system_check/system_check.sh' )
        color_wrong = 'background-color: Red'
        color_true = 'background-color: Green'
        color_unknown = 'background-color: white'
        color = [0, 0, 0, 0, 0]
        for i in range(len(check_result)):
            if check_result[i] == 0:
                color[i] = color_true
            elif check_result[i] == -1:
                color[i] = color_wrong
            else:
                color[i] = color_unknown
        self.label_1.setStyleSheet(color[0])
        self.label_2.setStyleSheet(color[1])
        self.label_3.setStyleSheet(color[2])
        self.label_4.setStyleSheet(color[3])
        self.label_5.setStyleSheet(color[4])
  

    def closeEvent(self, event):
        """
        对MainWindow的函数closeEvent进行重构
        退出软件时结束所有进程
        :param event:
        :return:
        """
        reply = QtWidgets.QMessageBox.question(self,
                                               '本程序',
                                               "是否要退出程序？",
                                               QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
                                               QtWidgets.QMessageBox.No)
        if reply == QtWidgets.QMessageBox.Yes:
            process_kill = subprocess.Popen("./startup_sh/host_kill.sh", shell=True)
            event.accept()
            os._exit(0)
            # process_kill = subprocess.Popen("./startup_sh/host_kill.sh", shell=True)
        else:
            event.ignore()

# choose massage mode
class MyWindow_mode(QMainWindow, Ui_mode_choose):
    def __init__(self, parent=None):
        super(MyWindow_mode, self).__init__(parent)
        self.setupUi(self)  # 这三行必须要有，ui——open载入open界面，（Qt生成open.ui文件，通过工具转成open.py文件）
        self.start_flag = False
        self.yaml_name = 'user.yaml'
        self.yaml_pub = rospy.Publisher("/massage/yaml_flag", Bool, queue_size=1)
        global data_path, yaml_path

    def custom(self):  # 选择自定义模式
        " "


    def tuntui_massage(self): # 臀腿按摩
        f = open(data_path + 'default_tuntui.yaml', 'r', encoding='utf-8')
        data_dict = yaml.load(f, Loader=yaml.FullLoader)

        with open(yaml_path + 'user' + '.yaml', "w") as f:
            yaml.dump(data_dict, f, encoding="utf-8", allow_unicode=True)
        print('tuntui massage output succeed')
        self.start_flag = True
        self.flag_publish()

    def yaobei_massage(self):  # 腰背按摩
        f = open(data_path + 'default_yaobei.yaml', 'r', encoding='utf-8')
        data_dict = yaml.load(f, Loader=yaml.FullLoader)

        with open(yaml_path + 'user' + '.yaml', "w") as f:
            yaml.dump(data_dict, f, encoding="utf-8", allow_unicode=True)
        print('yaobei massage output succeed')
        self.start_flag = True
        self.flag_publish()

    def flag_publish(self):
        k = 0
        while not rospy.is_shutdown():
            if k > 30:
                break
            self.yaml_pub.publish(self.start_flag)
            r = rospy.Rate(30)
            k = k + 1
            print('publish succeed')
            r.sleep()

    def closeEvent(self, event):
        """
        对MainWindow的函数closeEvent进行重构
        退出软件时结束所有进程
        :param event:
        :return:
        """
        reply = QtWidgets.QMessageBox.question(self,
                                               '本程序',
                                               "是否要退出程序？",
                                               QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
                                               QtWidgets.QMessageBox.No)
        if reply == QtWidgets.QMessageBox.Yes:
            event.accept()
            os._exit(0)
        else:
            event.ignore()

# choose acupoint data
class MyWindow_acupoint(QMainWindow, Ui_Acupoint_choose):
    def __init__(self, parent=None):
        super(MyWindow_acupoint, self).__init__(parent)
        self.setupUi(self)  # 这三行必须要有，ui——open载入open界面，（Qt生成open.ui文件，通过工具转成open.py文件）
        self.user_name = 'default'
        self.Acu_data = []

    def add_data(self):
        cur_direction_index = self.choose_direction.currentIndex()
        print('cur_direction', cur_direction_index)
        if cur_direction_index == 0:
            cur_direction_index = 'l'
        else:
            cur_direction_index = 'r'

        cur_method_index = self.choose_method.currentIndex()
        if cur_method_index == 4:
            cur_method_index = -1
        # if cur_method_index == 2:
        #     # QMessageBox.about(self,'提示','捏法不能如此使用')
        #     QMessageBox.about(self, QMainWindow, "标题", "关于对话框消息正文")
        cur_Acu_name = self.choose_Acupoint.value()
        cur_time = self.choose_time.value()
        data_new = [{'name': str(cur_direction_index)+'_BL'+str(cur_Acu_name), 'method':cur_method_index,'time':cur_time}]
        print(data_new)
        self.Acu_data.extend(data_new)
        print(self.Acu_data)

    def write_data(self):
        global yaml_path,data_path
        data_dict={'actions': self.Acu_data, 'name': self.user_name}
        # 存入用户库
        with open(data_path + self.user_name + '.yaml', "w") as f:
            yaml.dump(data_dict, f, encoding="utf-8", allow_unicode=True)
        # 传给机器人
        with open(yaml_path + 'user' + '.yaml', "w") as f:
            yaml.dump(data_dict, f, encoding="utf-8", allow_unicode=True)
        print('new user name', self.user_name)
        # data2 = json.dumps([self.Acu_data])

    def get_name(self):
        global user_name
        self.user_name = user_name
        print('name', user_name)

    def closeEvent(self, event):
        """
        对MainWindow的函数closeEvent进行重构
        退出软件时结束所有进程
        :param event:
        :return:
        """
        reply = QtWidgets.QMessageBox.question(self,
                                               '本程序',
                                               "是否要退出程序？",
                                               QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
                                               QtWidgets.QMessageBox.No)
        if reply == QtWidgets.QMessageBox.Yes:
            event.accept()
            os._exit(0)
        else:
            event.ignore()

# show acupoint data
class MyWindow_show(QMainWindow, Ui_Acupoint_show):
    def __init__(self, parent=None):
        super(MyWindow_show, self).__init__(parent)
        self.setupUi(self)  # 这三行必须要有，ui——open载入open界面，（Qt生成open.ui文件，通过工具转成open.py文件）
        self.maintain_flag = True
        self.Acupoint = 'BL11'
        self.method = '揉法'
        self.start_time = time.time()
        self.now_time = self.start_time
        self.massage_time = 3
        # 测试用 ，没有图片话题发布时可开启这个
        # self.picture = cv2.imread('C:\\Users\\94281\\Pictures\\1.png ') 

        self.Acupoint_img_sub = rospy.Subscriber("/k4a/color/color", Image, self.ros_img_callback)
        self.image = None
        self.count = 0
        self.start_time_flag = False

    def ros_img_callback(self, image_msg):
        bridge = CvBridge()
        self.image = bridge.imgmsg_to_cv2(image_msg, "bgr8")
        # cv2.imshow('Acupoint', self.image)
        # cv2.waitKey(3)
        # print('444')
        self.count = 1
        # print("call back get")

    def update_acu_image(self):
        while not rospy.is_shutdown():
            if thstop1:
                return
            if self.count == 0:
                continue
            # print('count', self.count)

            self.picture = self.image
            self.label_Acupoint.setText(self.Acupoint)
            self.label_Acupoint.setFont(QFont("Microsoft YaHei UI", 20, QFont.Bold))
            self.label_method.setText(self.method)
            self.label_method.setFont(QFont("Microsoft YaHei UI", 20, QFont.Bold))
            self.label_time.setNum(self.massage_time)
            self.label_time.setFont(QFont("Microsoft YaHei UI", 20, QFont.Bold))
            self.show_pic()
        return

    def time_initial(self):
        self.start_time_flag = True
        self.start_time = time.time()
        self.now_time = time.time()

    def show_pic(self):
        img2 = cv2.cvtColor(self.picture, cv2.COLOR_BGR2RGB)  # opencv读取的bgr格式图片转换成rgb格式
        _image = QtGui.QImage(img2[:], img2.shape[1], img2.shape[0], img2.shape[1] * 3,
                              QtGui.QImage.Format_RGB888)  # pyqt5转换成自己能放的图片格式
        jpg_out = QtGui.QPixmap(_image).scaled(self.label_pic.width(), self.label_pic.height())  # 设置图片大小
        self.label_pic.setPixmap(jpg_out)  # 设置图片显示

    def finish(self):
        # thstop = True
        # thstop1 = True
        # sys.exit(app.exec_())
        os._exit(0)

    def closeEvent(self, event):
        """
        对MainWindow的函数closeEvent进行重构
        退出软件时结束所有进程
        :param event:
        :return:
        """
        reply = QtWidgets.QMessageBox.question(self,
                                               '本程序',
                                               "是否要退出程序？",
                                               QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
                                               QtWidgets.QMessageBox.No)
        if reply == QtWidgets.QMessageBox.Yes:
            event.accept()
            os._exit(0)
        else:
            event.ignore()


# ----------------------------------------------------------------------------------#
# def update_state():
#     while True:
#         if thstop:
#             return
#         w_show.now_time = time.time()
#         dt = abs(w_show.now_time - w_show.start_time)
#         if dt < 5 or dt > 10:
#             # print('1')
#             # print(w_show.now_time - w_show.start_time)
#             w_show.massage_time = 1
#             w_show.method = '滚法'
#             w_show.picture = cv2.imread('/home/massage/Downloads/0529_18.jpg')
#         else:
#             # print('2')
#             # print(w_show.now_time - w_show.start_time)
#             w_show.massage_time = 4
#             w_show.method = '揉法'
#             w_show.picture = cv2.imread('/home/massage/Downloads/0529_19.jpg')
#         if abs(w_show.now_time - w_show.start_time) > 15 and w_show.start_time_flag:
#             # print('========================================================================3')
#             # print(w_show.now_time - w_show.start_time)
#             break

#         w_show.label_Acupoint.setText(w_show.Acupoint)
#         w_show.label_Acupoint.setFont(QFont("Microsoft YaHei UI", 20, QFont.Bold))
#         w_show.label_method.setText(w_show.method)
#         w_show.label_method.setFont(QFont("Microsoft YaHei UI", 20, QFont.Bold))
#         w_show.label_time.setNum(w_show.massage_time)
#         w_show.label_time.setFont(QFont("Microsoft YaHei UI", 20, QFont.Bold))
#         w_show.show_pic()
#     return


# /***********------------------------主函数---------------------------------------------********/

# 初始化
QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
app = QApplication(sys.argv)
rospy.init_node("Acupoint_gui", anonymous=True)

# if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
#     QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);


# 实例化各个界面类
w_start = MyWindow_start()  # 封面
w_check = MyWindow_check()  # 系统自检界面
w_user = MyWindow_user()  # 新老用户选择界面
w_mode = MyWindow_mode()  # 按摩模式选择界面
w_acupoint = MyWindow_acupoint()  # 按摩序列录入界面
w_show = MyWindow_show()  # 后台监控窗口

# 开始界面
w_start.show()
w_start.Open.clicked.connect(w_check.show)  # 点击开始按钮，基本信息界面显示
# w_start.Open.clicked.connect(w_start.begin_process)  # 点击开始按钮，启动节点
w_start.Open.clicked.connect(w_start.begin_process_with_new_terminate)  # 点击开始按钮，新终端启动节点

# w_start.Open.clicked.connect(w_start.close)  # 点击开始按钮，第一个界面关闭


# 系统自检界面
w_check.Button_finish.clicked.connect(w_user.show)  # change to next ui
# w_check.Button_finish.clicked.connect(w_check.close)
w_check.Button_start.clicked.connect(w_check.check)

# # 选择新老用户界面
# 读取姓名
w_user.NameButton.clicked.connect(w_user.get_name)
# 选择新用户
w_user.pushButton_new.clicked.connect(w_acupoint.get_name)
w_user.pushButton_new.clicked.connect(w_mode.show)
# w_user.pushButton_new.clicked.connect(w_user.close)
# 选择老用户
w_user.pushButton_old.clicked.connect(w_user.get_old_data)
w_user.pushButton_old.clicked.connect(w_show.show)
# w_user.pushButton_old.clicked.connect(w_user.close)


# 按摩模式选择界面
w_mode.demo_custom.clicked.connect(w_acupoint.show)
w_mode.demo_tuntui.clicked.connect(w_mode.tuntui_massage)  # 臀腿
w_mode.demo_tuntui.clicked.connect(w_show.show)
w_mode.demo_yaobei.clicked.connect(w_mode.yaobei_massage)  # 腰背
w_mode.demo_yaobei.clicked.connect(w_show.show)
# w_mode.demo_custom.clicked.connect(w_mode.close)

# 按摩序列采集界面
w_acupoint.Buttion_add.clicked.connect(w_acupoint.add_data)
w_acupoint.Button_finish.clicked.connect(w_acupoint.write_data)
w_acupoint.Button_finish.clicked.connect(w_show.show)
# w_acupoint.Button_finish.clicked.connect(w_acupoint.close)
w_acupoint.Button_finish.clicked.connect(w_show.time_initial)


# # 按摩状态显示界面
w_show.Button_finish.clicked.connect(w_show.finish)
# th = Thread(target=update_state)
th = Thread(target=w_show.update_acu_image)
# # th.setDaemon(True)
th.start()

app.exec_()

# 退出的时候,结束进程,否则,关不掉进程
thstop = True
thstop1 = True

sys.exit(app.exec_())